home *** CD-ROM | disk | FTP | other *** search
- #############################################################################
- Recipes for MPW C++ 1.0
- Kent Sandvik DTS Sunday, June 14, 1992 15:37:54
-
- Permission to republish this is granted, as long as the contents
- are not modified/altered/shortened in any way without consulting the author first.
-
- Place in MPW Folder, and put following line (example) in UserStartup:
- AddMenu Special 'C++ Recipes/1' 'Open "{MPW}Recipes.C++"'
- ^ triggered from option-1
-
- Please redirect any comments, bug reports and such to:
- ksand@apple.com (Usenet, Internet)
- KSAND (AppleLink)
- 75300, 1331 (CompuServe)
-
- References:
- C++ Programming Language (second edition), Bjarne Stroustrup
- Annotated C++ Reference Manual, Ellis & Stroustrup
- All kinds of private notes/hacks (Usenet comp.lang.c++, CompuServe)
-
- Future plans:
- * more material, bug fixes, better explanations
- * 411 (template/lookup support), or something more hypertext:ish
-
- Thanks!
- Johan Strandberg, Common Knowledge
-
- #############################################################################
-
-
-
-
- // C++ CLASS TEMPLATE
- #include <stream.h>
-
- class TFoo
- {
- public:
- TFoo(); // constructor
- ~TFoo(); // destructor
-
- protected:
- long fField;
- private:
- };
-
-
-
-
- // Method implementations
- TFoo::TFoo() // constructor
- {
- cout << "inside TFoo constructor\n";
- }
-
-
- TFoo::~TFoo() // destructor
- {
- // empty for the moment
- }
-
-
-
-
- class TBar : public TFoo
- {
- public:
- TBar()
- {
- cout << "inside TBar constructor\n";
- }
-
-
- virtual void Member();
- };
-
-
-
- void TBar::Member()
- {
- cout << "inside TBar::Member\n";
- }
-
-
-
-
- TBar* aBar;
-
- main()
- {
- aBar = new TBar;
- return 0;
- }
-
-
-
-
- // VOLATILE MACRO
- #define VOLATILE(a) ((void) &a)
-
-
-
- // GLOBAL SCOPE OPERATOR
- int x;
-
- void func()
- {
- int x = 1; // use local x
- ::x = 2; // use global x
- }
-
-
-
- // void POINTERS - can be made to point at anything
- void* malloc(unsigned size); // C style memory allocation
- void free(void*);
-
- void func()
- {
- int* pi = (int*)malloc(10 * sizeof(int));
- char* pc = (char*)malloc(10);
- // ...
- free(pi);
- free(pc);
- }
-
-
-
-
-
-
- // POINTERS
- int* pi; // pointer to int
- char** cpp; // pointer to array to char
- int(* vp)[10]; // pointer to array of 10 ints
- int(* fp)(char,
- char*); // pointer to function taking
- // (char, char*), returning int
-
- char c1 = 'a'; // c1 contains 'a'
- char* p = &c1; // p contains address of c1
- char c2 = *p; // c2 contains 'a'
-
- size_t strlen(char* p)
- {
- size_t i = 0;
- while (*p++)
- i++;
- return i;
- }
-
-
-
- // FASTER POINTER STRING COMPARISON - produces better code on most platforms
- int strlen(const char* p)
- {
- register char* q = p;
- while (*q++)
- return q - p - 1;
- }
-
-
-
-
- // ARRAYS
- float v[3]; // array of 3 floats
- int a[3][5]; // 2-dimensional array of ints (3 times 5)
- char* vpc[32]; // array of 32 char pointers
-
- int v1[1] = {
- 1, 2, 3, 4}; // assigment of array elements
-
-
-
- // POINTERS AND ARRAYS
- char* p = &alpha[0]; // make p point at start of alpha array
- char* p = alpha; // same semantics!
-
- extern "C"
- int strlen(const char*);
- void func()
- {
- char v[] = "Jeff Steven"
- char* p = v;
- strlen(p);
- strlen(v); // both gives same value
- }
-
-
-
-
- // STRUCTURES
- struct address
- {
- char* name;
- long number;
- char* street;
- char* town;
- char state[2];
- long zip;
- };
-
-
- address js;
- js. name = "Jeff Sandvik";
- js. number = 20200;
-
-
- address js = { // struct assignment
- "Jeff Sandvik", 20200, "Lucille Ave", "Cupertino", {'C', 'A'}, 95104};
-
-
- void printAddress(address p) // struct pointer handling
- {
- cout << p->name << '\n' << p->number << ' '
- << p->street << '\n' << p->town << '\n'
- << p->state[0] << p->state[1] << ' '
- << p->zip << '\n'
- }
-
-
-
- address current;
-
- address setCurrent(address next) // address handling
- {
- address prev = current;
- current = next;
- return prev;
- }
-
-
- struct link
- { // struct self referencing
- link* previous;
- link* next;
- };
-
-
-
-
-
- // typedef
- typedef char* Pchar;
- Pchar p1, p2;
- char p3 = p1;
-
-
- // REFERENCES (&)
- int i = 1; // example
- int& r = i;
- int x = r; // x = 1;
- r = 2; // i = 2;
-
- void incr(int& a)
- {
- a++;
- } // function call
-
-
- void func()
- {
- int x = 1;
- incr(x); // x = 2;
- }
-
-
-
-
- // const
- const int model = 100;
- model = 200; // error!
-
- const char* pc = "abc"; // const pc data
- pc[3] = 'a'; // error!
- pc = "def"; // ok
-
- char* const cp = "abc"; // constant pointer
- cp[3] = 'a'; // ok
- cp = "def"; // error!
-
- const char* const pc "abc"; // data and pointer constant
-
- char* strcpy(char* p,
- const char* q); // can't modify q
-
-
- // ENUMS
- enum
- {
- kRed, kBlue, kGreen
- }; // enum list, kRed = 0, kBlue = 1...
-
-
- enum
- {
- kRed = 200, kBlue, kGreen = 300
- }; // kBlue = 201
-
-
- enum EColors
- {
- kRed, kBlue, kGreen
- }; // named enum
-
-
- eColors returnColor();
-
- eColors theColor;
-
- switch (theColor){
- case kRed:
- // do something
- break;
- case kBlue:
- // do something
- break;
- case kGreen:
- // do something
- break;
- default:
- // do something
- break;
- };
-
- class foo
- {
- public:
- enum eColors
- {
- eRed, eBlue, eGreen
- };
- //...
-
- };
-
-
-
- myClass. fColor = foo::eRed;
-
-
- // BITFIELDS
- struct ASICReg {
- unsigned enable: 1; // one bit
- unsigned page: 3; // three bits
- unsigned : 1; // unused
- unsigned mode: 2; // two bits
- unsigned : 4; // unused
- unsigned access: 1; // one bit
- unsigned length: 1;
- unsigned non_res: 1;
- };
-
- ASICReg* SR = (sreg *)0xA800; // fictiv address, memory mapped I/O
- // ...
-
- if (SR->access) // true?
- {
- // clean up the state
- SR->access = 0;
- }
-
-
- // UNIONS
- struct entry {
- char* name;
- char type; // tagged value for union
- union
- {
- char* stringValue; // char string type = 's'
- int intValue; // or int variable type = 'i'
- };
-
-
- };
-
- union foo
- { // named union
- int i;
- int* p;
- };
-
-
-
-
- // MODULO
- const int RANGE = 100;
- int i;
-
- i%= RANGE; // i is in the range 0...RANGE-1
-
-
- // BITWISE LEFT SHIFT
- int i = 0x8000;
- i<<= 1; // left shift one step
-
-
- // BITWISE XOR
- int i = 0x8000;
- i^= 0x3000; // note, no space between ^ and =!!!
-
- // BITWISE OR
- int i = 0x8000;
- i|= 0x3000;
-
- // BITWISE AND
- int i = 0x8000;
- i&= 0x3000;
-
-
- // ERROR STREAMS
- int numErrors;
-
- double error(const char* s)
- {
- cerr << "error: " << s << "\n";
- numErrors++;
- return 1;
- }
-
-
-
-
- // TYPE CONVERSION
- int foo = 56;
- float bar = float(foo);
-
- char* p = (char*)0xA800; // typecast of address
- typedef char* Address;
- Address p = Address(0xA800); // same as above
-
-
- // free store (new, delete, set_new_handler...)
-
- main() // simple example
- {
- char* p = saveString("foobar");
- delete[]p; // note new 2.0 delete syntax
- }
-
-
- char* saveString(const char* p)
- {
- char* s = new
- char[strlen(p) + 1];
- strcpy(s, p);
- return s;
- }
-
-
-
- TFoo* aFoo = new TFoo; // create object in the free store (heap on MacOS)
-
- #include <stream.h>
- #include <new.h>
-
- void OutofStore()
- {
- cerr << "operator new failed : out of store\n";
- exit(1);
- }
-
-
- main()
- {
- set_new_handler(&OutOfStore); // give address to handler
- char* p = new
- char[100000000000];
- cout << "what, it works..., address = ", long(p)<< '\n';
- // new returns 0 if it can't find enough memory - test for NULL
- }
-
-
-
-
-
- // STACK BASED OBJECTS
- void func()
- {
- TFoo aFoo; // local -> placed on the stack
- aFoo.Beep();
- } // removed from stack automatically
-
-
-
-
- // ? : CONDITIONAL EXPRESSION
- max = (a <= b) ? b : a;
-
-
- // LINKAGE TO NON-C++ CODE - no function name mangling
- #ifdef __cplusplus
- extern "C"
- {
- #endif
-
- pascal Handle NewHandle(Size byteCount)
- #pragma parameter DisposHandle(__A0)
- pascal void DisposHandle(Handle h) = 0xA023;
- #ifdef __cplusplus
- }
- #endif
-
- extern "C"
- {
- char* strcpy(char* ,
- const char*);
- int strcmp(const char* ,
- const char*);
- // ...
- }
-
-
- extern "C"
- {
- #include "myCHeaderFiles.h"
- }
-
-
-
-
- // RECURSION
- int fac(int n)
- {
- return (n > 1) ? n * fac(n - 1) : 1;
- }
-
-
-
-
- // OVERLOADED FUNCTION NAMES
- void print(int); // integer print
- void print(const char*); // string print
-
-
- // DEFAULT FUNCTION ARGUMENTS
- void print(int value,
- int base = 10);
- //...
- print(30); // will use base=10 inside print
-
- void foo(int,
- char* ,
- int = 0,
- char*= 0);
- // have to define defaults from right!
-
-
-
- // UNSPEFIFIED AMOUNT OF FUNCTION ARGUMENT
- int printf(const char ...);
-
-
- // POINTERS TO FUNCTIONS
- void error(char* p)
- {
- /* ... */
- }
-
-
- void(* efunc)(char*); // pointer to function
-
- void func()
- {
- efunc = &error; // give address to function ptr
- (*efunc)("mayday"); // call the function via ptr
- }
-
-
-
- typedef void(* PF)();
-
- PF editOps[] = { // edit operations
- &cut, &paste, ©};
-
- PF fileOps[] = {
- &new, &save, &close};
-
- PF MenuEntry = editOps;
- //...
- (*MenuEntry[3])(); // selected copy! trigger copy function
-
-
- // MACROS
- #define print(a,b) cout << (a) << (b) // argument usage
- #define forever for(;;)
- #define MIN(a,b) (((a)<(b))?(a):(b))
-
-
-
- // this POINTER
- //always defined as X *const this; where X is the name of the class
-
- class X
- {
- int m;
- public:
- int readm()
- {
- return this->m;
- } // makes things more clear!
-
-
-
-
- class dlink
- {
- dlink* previous;
- dlink* successor;
- public:
- void append(dlink*);
- // ...
- };
-
-
-
- void dlink::append(dlink* p)
- {
- p->successor = successor;
- p->previous = this;
- successor->previous = p;
- successor = p;
- }
-
-
-
- dlink* listHead;
- void func(dlink* a,
- dlink* b)
- {
- // ...
- listHead->append(a);
- listHead->append(b);
- }
-
-
-
-
- // const MEMBER FUNCTIONS
- class X
- {
- int m;
- public:
- readme() const
- {
- return m;
- } // const member function, read-only
-
-
- writeme(int i)
- {
- m = i;
- }
-
-
- };
-
-
-
- // you are able to change a value through an explicit this cast:
- class X
- {
- int m;
- public:
- // ...
- void implicitCheat() const
- {
- m++;
- } // error!
-
-
- void explicitCheat() const
- {
- ((X *)this)->m++;
- } // ok
-
-
- };
-
-
-
-
- // const CLASSES
- void func(X& mutable,
- const X& constant)
- {
- mutable.readme(); // ok
- mutable.writeme(7); // ok
- constant.readme(); // ok
- constant.writeme(7); // error
- }
-
-
-
-
- // CONSTRUCTORS
- class TDate
- {
- // ...
- TDate(int day,
- int month,
- long year); // constructor
- TDate(int month,
- long year); // other form
- TDate(long); // 910915, ANSI standard
- TDate(); // default today's date
- TDate(const char*); // string "Sun 15 Sept 1991"
- TDate(int d = 0,
- int m = 0,
- long year = 0); // default values
- };
-
-
- TDate today(15,
- 9,
- 1991); // stack based class
- TDate tomorrow("Mon 16 Sept 1991");
- TDate now; // today's date
- TDate d = today; // default copy constructor! bitwise copy
-
- TDate::TDate(int d,
- int m,
- long y) // constructor function declaration
- {
- // ...
- }
-
-
-
-
- // DESTRUCTORS
- class TStack
- {
- int size;
- char* top;
- char* s;
- public:
- TStack(int sz)
- {
- top = s = new
- char[size = sz];
- }
-
-
- ~TStack()
- {
- delete[]s;
- } // destructor
-
-
- void push(char c)
- {
- *top++ = c;
- }
-
-
- void pop()
- {
- return *--top;
- }
-
-
- };
-
-
- void func()
- {
- TStack s1(100);
- TStack s2(200);
- s1.push('a');
- s2.push('b');
- char ch = s2.pop();
- cout << ch << '\n';
- } // automatic call of destructor
-
-
-
-
-
- // inline CALLS - (see ARM 102 and TN307 for more info when compiler will not inline
- class TFoo
- {
- public:
- void func1()
- {
- /*...*/
- } // this code is inlined
-
-
- void func2();
- };
-
-
- inline void TFoo::func2()
- {
- // this code is inlined
- // ...
- }
-
-
-
-
- // friend USE
- class x
- {
- friend class y; // class y has access to x's private parts
- // ...
- };
-
-
- class x
- {
- friend void y::f(); // y::f() member function has access to
- //... // x's private parts
- };
-
-
-
-
- // CLASS MEMBER NAME QUALIFICATION
- class X
- {
- int m;
- public:
- int getm() const
- {
- return m;
- }
-
-
- void setm(int m)
- {
- X::m = m;
- } // name qualification
-
-
- };
-
-
- class TFile()
- {
- // ...
- int open(const char* ,
- const char*);
- }
-
-
- ;
-
- int TFile::open(const char* name,
- const char* spec)
- {
- // ...
- if (::open(name, flag))
- {
- // stdclib open called
- // ...
- }
- // ...
- }
-
-
-
-
- // NESTED CLASSES
- class TSet
- {
- struct setmem
- {
- int mem;
- setmem* next;
- setmem(int m,
- setmem* n)
- {
- mem = m;
- next = n;
- }
-
-
- };
-
-
- setmem* first; // nested class struct
- public:
- TSet()
- {
- first = NULL;
- }
-
-
- insert()
- {
- first = new setmem(m, first);
- }
- // ...
-
- };
-
-
-
-
- // nicer with friends:
- class TSetmem
- {
- friend class TSet; // access to members of TSet only
- int mem;
- setmem* next;
- setmem(int m,
- setmem* n)
- {
- mem = m, next = n;
- }
- // other useful members
-
- };
-
-
- class TSet
- {
- setmem* first;
- public:
- TSet()
- {
- first = NULL;
- }
-
-
- insert(int m)
- {
- first = new setmem(m, first);
- }
- // ...
-
- };
-
-
- class X
- { // name scoping
- private:
- struct M1
- {
- int m;
- }
- public:
- struct M2
- {
- int m;
- } M1 f(M2); // member function
- };
-
-
- void func()
- {
- M1 a; // error, 'M1' not in scope
- M2 b; // ok
- X::M1 c; // error, 'M1' private
- X::M2 d; // ok
- }
-
-
-
-
- // static CLASS MEMBERS
- class TTask
- {
- public:
- // ...
- static TTask* chain; // static field, one copy of the TTask only
- static void Schedule(); // static member function
- // ...
- };
-
-
-
- TTask* TTask::chain = NULL;
- void TTask::Schedule()
- {
- /* ....*/
- }
-
-
- ;
-
- ....
- if(TTask::chain == NULL) // must be qualified by class name
- {
- // do something
- }
-
- TTask::Schedule(); // call the static member function
-
-
- // POINTERS TO MEMBER FUNCTIONS
- typedef long(TFoo::* Function)();
- enum eGenerator
- {
- SIMPLE, PRACTICAL, COMPLEX
- };
-
-
-
- class TFoo
- {
- private:
- Function fGenerator; // pointer to Generate function
- int fVal;
- public:
- TFoo(eGenerator);
- long Simple()
- {
- return 2;
- }
-
-
- long Practical()
- {
- return 4;
- }
-
-
- ;
- long Complex()
- {
- return 6;
- }
-
-
- long Generate()
- {
- return this->*fGenerator();
- } // use the function fGenerator is pointing at
-
-
- };
-
-
-
- TFoo::TFoo(eGenerator theGenerator)
- {
- switch(theGenerator) // set pointer to defined function
- {
- case SIMPLE:
- this->fGenerator = &TFoo:Simple;
- break;
- case PRACTICAL:
- this->fGenerator = &TFoo::Practical;
- break;
- case COMPLEX:
- this->fGenerator = &TFoo:Complex;
- }
- }
-
-
-
-
-
- // CLASS OBJECTS AS MEMBERS
- class TClassDef
- {
- table members;
- int numMembers;
- // ...
- TClassDef(int size);
- ~TClassDef();
- };
-
-
-
- TClassDef::TClassDef(int size) :
- members(size) // pass information for init
- {
- numMembers = size;
- // ...
- }
-
-
- // ARRAYS OF CLASS OBJECTS
- TTable tbl[10]; // will generate an array of 10 TTable objects
-
-
- // new/delete OPERATOR OVERLOADING
- class TName
- {
- public:
- char* string;
- TName* next;
- double value;
-
- TName(char* ,
- double name*);
- ~TName();
-
- void* operatornew(size_t);
- void operatordelete(void* ,
- size_t);
- private:
- enum
- {
- N_ALL = 128
- };
-
-
- static name* nfree;
- };
-
-
-
- void* TName::operatornew(size_t)
- {
- register TName* p = nfree; // first allocate
-
- if (p)
- nfree = p->next;
- else
- {
- TName * q = (TName *)new
- char[N_ALL * sizeof(name)];
- for (p = nfree = &q[N_ALL - 1]; q < p; p--)
- p->next = p - 1;
- p->next = NULL;
- }
- return p;
- }
-
-
-
- void TName::operatordelete(void* p,
- size_t)
- {
- ((TName *)p)->next = nfree;
- nfree = (TName *)p;
- }
-
- //....
- * TName::nfree = 0; // explicit initialization of the value
-
-
-
- // DERIVED CLASSES
- class TEmployee
- {
- private:
- char* name;
- short age;
- short department;
- public:
- TEmployee();
- print() const
- {
- /*...*/
- }
-
-
- TEmployee* next;
- }
-
- class TManager : public TEmployee
- {
- TEmployee* group;
- short level;
- public:
- TManager();
- print() const
- {
- /*...*/
- }
-
-
- };
-
-
- void TEmployee::print()
- {
- cout << "Employee information...\n";
- }
-
-
- void TManager::print()
- {
- TEmployee::print(); // print employee information
- cout << "Manager information...\n";
- }
-
-
- void func()
- {
- TManager m1, m2;
- TEmployee e1, e2;
- TEmployee * elist;
-
- elist = &m1; // put m1 on elist
- m1.next = &e2; // put e1 on elist
- e1.next = &m2;
- m2.next = &e2;
- e2.next = NULL; // last in the elist
- }
-
-
- void g()
- {
- TManager MM;
- Temployee * pe = &MM; // ok
-
- TEmployee ee;
- manager * PM = ⅇ // error, not every TEmployee is a TManager
-
- PM->level = 2; // won't work, no space for level
-
- PM = (TManager *)pe; // ok
- PM->level = 2; // ok
- }
-
-
-
-
- // DERIVED CONSTRUCTORS & DESTRUCTORS
- // class objects are constructed from the bottom up, first the base,
- // then the members, then the derived class itself. They are destroyed
- // in the opposite order
-
- class TEmployee
- {
- // ...
- public:
- TEmployee(char* n,
- int d);
- };
-
-
- class TManager:: public TEmployee
- {
- // ....
- public:TManager(char* n, int l, int d);
- }
-
-
- ;
-
- TEmployee::TEmployee(char* n,
- int d) :
- name(n),
- department(d)
- {
- next = list;
- list = this;
- }
-
- TManager::TManager(char* n,
- int l,
- int d) :
- TEmployee(n, d),
- level(l),
- group(0)
- {
- //...
- }
-
-
- // CLASS HIERARCHIES
- class TEmployee { /* .... */ };
- class TManager: public TEmployee {/* .... */};
- class TDirector: public TManager {'* .... */};
- class TTemporary {/* ....*/};
-
-
- // MULTIPLE INHERITANCE
- class TConsultant: public TManager, public TTemporary {/* .... */};
-
- class TTask
- {
- //
- virtual info* debug();
- };
-
-
-
- class TDisplayed
- {
- // ...
- virtual info* debug();
- };
-
-
-
-
- class TSatellite : public TTask, public TDisplayed
- {
- // ...
- };
-
-
-
- void func(TSatellite& s) // ambiguity with member function names
- {
- s.draw(); // TDisplayed::draw()
- s.delay(10); // TTask::delay(int x);
- s.xmit(); // TSatellite::Xmit()
-
- info * d_info = s.debug; // ambiguity problems!
- d_info = s.TTask::debug(); // ok
- d_info = s.TDisplayed::debug() // ok
-
- // with pointers, TSatellite *s
- d_info = s->TTask::debug();
- d_info = s->TDisplayed::debug();
- }
-
-
-
- // better to define new member functions inside TSatellite!
- class TSatellite : public TTask, public TDisplayed
- {
- // ...
-
- info* satelliteDebug()
- {
- info * d1 = TTask::debug();
- info * d2 = TDisplayed::debug();
- return d1.merge(d2);
- }
-
-
- };
-
-
-
-
- // VIRTUAL FUNCTIONS
- class TEmployee
- {
- char* name;
- short department;
- // ...
- TEmployee* next;
- static TEmployee* list;
- public:
- TEmployee(char* n,
- int d);
- // ..
- static void printList();
- virtual void print() const; // virtual function, can be
- }; // overridden
-
-
-
- ....
- void TEmployee::print() const
- {
- cout << name << '\t' << department << '\n';
- // ...
- }
-
-
-
- class TManager:: public TEmployee
- {
- TEmployee * group;
- short level;
- // ...
- public:TManager(char* n, int l, int d);
- // ...
- void print const(); // we could override this - virtual
- }
-
-
- ;
-
- ....
- void TManager::print() const
- {
- cout << level << '\n';
- //...
- }
-
-
-
-
- // ABSTRACT CLASSES - PURE VIRTUAL FUNCTIONS
- class TShape
- { // has pure virtual function = abstract class
- // ...
- public:
- virtual void rotate(int x) = 0; // pure virtual function
- };
-
-
- class TMyShape
- {
- // ...
- public:
- virtual void rotate(int x)
- {
- /* ... */
- } // have to create this member function
-
-
- };
-
-
-
- ...
- TShape aShape; // error!
- TMyShape anotherShape; // ok
-
-
- // virtual base classes
-
- class TWindow
- {
- // window information
- void _Draw(); // internal window draw
- virtual void Draw()
- {
- _Draw();
- } // calls by default _Draw()
-
-
- };
-
-
-
- class TWindowBorder : public virtual TWindow
- {
- // border information
- void _Draw(); // draw border
- void Draw();
- };
-
-
-
- class TWindowMenu : public virtual TWindow
- {
- // menu information
- void _Draw(); // draw menu
- void Draw();
- };
-
-
- class TWindowBorderMenu : public virtual TWindow, public TWindowBorder, public TWindowMenu
- {
- // ...
- void _Draw(); // draw specific stuff
- void Draw();
- };
-
-
-
- // every class defined virtual base class will be represented by a *single*
- // object of that class.
- void TWindowBorder::Draw()
- {
- TWindow::Draw();
- _Draw(); // draw the border
- }
-
-
- void TWindowMenu::Draw()
- {
- TWindow::Draw();
- _Draw(); // draw the menu
- }
-
-
- void TWindowBorderMenu::Draw()
- {
- TWindow::Draw();
- TWindowBorder::Draw();
- TWindowMenu::Draw();
- _Draw(); // draw specific stuff
- }
-
-
-
-
- // ACCESS CONTROL
- // private (class only), protected (shareable by inheritance),
- // public (open)
- class X
- {
- private: // no definition = private
- enum
- {
- A, B
- };
-
-
- void f(int x);
- int a;
- };
-
-
- void X::f(int x)
- {
- if (x < A)
- f(x + B);
- a++;
- }
-
-
- void g(X& x)
- {
- int i = X::A; // error, X::A is private
- x.f(2); // error, X::f() is private
- x.a++; // error X::a is private
- }
-
-
- // PROTECTED MEMBERS
- class X
- {
- // private by default
- int priv;
- protected:
- int prot;
- public:
- int publ;
- void m();
- };
-
-
- void X::m()
- {
- priv = 1; // ok
- prot = 2; // ok
- publ = 3; // ok
- }
-
-
- class Y : public X
- {
- void mDerived();
- };
-
-
- void Y::mDerived()
- {
- priv = 1; // error, priv is private inside X
- prot = 2; // ok, inherited
- publ = 3; // ok, public class
- }
-
-
- void f(Y* p)
- {
- p->priv = 1; // error, priv is private
- p->prot = 2; // error, prot is protected, and no inheritance
- p->publ = 3; // ok, public class
- }
-
-
-
-
- // ACCESS TO BASE CLASS
- class X
- {
- public:
- int a;
- // ...
- };
-
-
- class Y1 : public X
- { /*...*/
- } class Y2 : protected X
- { /* ... */
- } class Y3 : private X
- { /* ... */
- } // private default
-
- void f(Y1* p1,
- Y2* p2,
- Y3* p3)
- {
- X * q1 = p1; // ok, X is a public base class of Y1
- p1->a = 7; // ok, internal reference to private field
- q1 = p2; // error, X is a protected base of Y2
- p2->a = 7; // error,
- q1 = p3; // error, X is a private base of Y3
- p3->a = 7; // error
- }
-
-
-
-
- // VIRTUAL DESTRUCTORS
- class TFoo
- {
- public:
- TFoo(); // constructor
- virtual~ TFoo(); // virtual destructor
- // ...
- };
-
-
-
- // this makes it possible for the compiler to keep track of each destructor
- // and the ordering. Most destructors should be virtual!
-
-
-
- // new - PLACEMENT OPERATOR
- class X
- {
- // ...
- public:
- X(int);
- };
-
-
-
- void* operatornew(size_t,
- void* p)
- {
- return p;
- }
-
-
-
- char buffer[sizeof(X)];
-
- void f(int i)
- {
- X * p = new(buffer)X(i); // place X in buffer!
- // ...
- }
-
-
-
- class TArena
- {
- // ...
- virtual void* alloc(size_t) = 0;
- virtual void free(void) = 0;
- };
-
-
- void* operatornew(size_t,
- sz,
- Arena* a)
- {
- return a.alloc(size);
- }
-
-
- ...
- extern Arena* Persistent;
- extern Arena* Shared;
-
- void g(int i)
- {
- X * p = new(Persistent)X(i); // X in persistent storage
- X * q = new(Shared)X(i); // X in shared memory
- // ...
- }
-
-
-
-
- void h(X* p)
- {
- p->~X(); // call destructor
- Persistent->free(p); // free actual memory
- }
-
-
-
-
- // OPERATOR OVERLOADING
- class TComplex
- { // class definition
- double re, im;
- public:
- TComplex(double r,
- double i = 0)
- {
- re = r, im = i;
- }
-
-
- friend complex operator+(TComplex,
- TComplex);
- friend complex operator*(TComplex,
- TComplex);
-
- TComplex& operator+=(TComplex);
- TComplex& operator-=(TComplex);
- };
-
-
-
- inline TComplex& TComplex::operator+=(TComplex a)
- {
- re += a.re;
- im += a.im;
- return this;
- }
-
-
- inline TComplex operator+(TComplex a,
- TComplex b)
- {
- return TComplex(a.re + b.re, a.im + b.im);
- }
-
-
-
-
- void f() // usage
- {
- complex a = complex(1, 3.1);
- complex b = complex(1.2, 2);
- complex c = b;
-
- a = b + c;
- b = b + c * a;
- c = a * b + complex(1, 2);
-
- complex d = operator+(a, b); // explicit call
- complex e = 23; // takes default i value
- }
-
-
-
-
- // CONVERSION OPERATORS
- class TTiny
- {
- char v;
- void assign(int i)
- {
- if (i > 63)
- {
- error("range error");
- v = i &~63;
- }
- v = i;
- }
-
-
- public:
- TTiny(int i)
- {
- assign(i);
- }
-
-
- TTiny(const TTiny& t)
- {
- v = t.v;
- }
-
-
- TTiny& operator=(const TTiny& t)
- {
- v = t.v;
- return *this;
- }
-
-
- TTiny& operator=(int i)
- {
- assign(i);
- return *this;
- }
-
-
- operator int()
- {
- return v;
- } // conversion operator!
-
-
- };
-
-
- void main()
- {
- TTiny c1 = 2;
- TTiny c2 = 62;
- TTiny c3 = c2 - c1; // c3 = 60
- TTiny c4 = c3; // no range check, not necessary
- int i = c1 + c2; // i = 64
- c1 = c2 + 2 * c1; // c1 = 2
- c2 = c1 - i; // c2 = 2
- c3 = c2; // no range check, not necessary
- }
-
-
-
-
- // COPY CONSTRUCTORS
- class TString
- {
- char* p;
- int size; // of vector pointed to by p
-
- TString(int sz)
- {
- p = new
- char[size = sz];
- }
-
-
- ~TString()
- {
- delete[]p;
- }
-
-
- TString& operator=(const TString&);
- TString(const TString&); // copy constructor!
- };
-
-
-
- TString::TString(const TString& a) // (if not defined, bitwise copy generated by compiler
- {
- p = new
- char[size = a.size];
- strcpy(p, a.p);
- }
-
-
- TString& TString::operator=(const TString& a)
- {
- if (this != &a)
- {
- delete[]p;
- p = new
- char[size = a.size];
- strcpy(p, a.p);
- }
- return *this;
- }
-
-
- void f()
- {
- TString s1(10);
- TString s2 = s1; // initialization, not assignment
- }
-
-
-
- // MEMBERVISE INITIALIZATION
- class TString
- {
- public:
- TString(const TString& s)
- //
- private:
- short len;
- char str[255];
- };
-
-
- TString(const TString&)
- {
- this->len = s.len;
- this->str = s.str;
- }
-
- //...
- TString foo = bar;
-
-
- // subscripting - operator [] overload
-
- #include <string.h>
-
- class TAssoc
- {
- struct pair
- {
- char* name;
- int val;
- };
-
-
- pair* vector;
- int max;
- int nfree;
-
- TAssoc(const& TAssoc&); // prevent copying
- TAssoc& operator=(const TAssoc&); // prevent assignment
- public:
- TAssoc(int);
- int& operator[](const char*); // operator [] overload
- void PrintAll();
- };
-
-
- TAssoc::TAssoc(int s)
- {
- max = (s < 16) ? s : 16;
- nfree = 0;
- vector = new pair[max];
- }
-
-
-
- int& TAssoc::operator[](const char* p)
- // maintain a set of pairs, search for p, return a reference to the
- // integer part of its "pair",, make a new "pair" if "p" has not been seen
-
- register pair* pp;
-
- for(pp = vector + free - 1 ; vector <= pp; pp--)
- if( strcmp(p,pp->name) == 0 ) return pp->val;
-
- if(nfree == max){ // overflow, grow the vector
- pair* newvec = new pair[max*2];
- for(int i=0; i < max; i++)
- newvec[i] = vector[i];
- delete [] vector;
- vector = newvector;
- max = 2*max;
- }
-
- pp = &vector[nfree++];
- pp->name = new char[strlen(p) + 1];
- strcpy(pp->name, p);
- pp->val = 0; // initial value
- return pp->val;
- }
-
- void TAssoc::PrintAll()
- {
- for (int i = 0; i < nfree; i++)
- cout << vector[i].name << ": " << vector[i].val << "\n";
- }
-
-
-
- main()
- {
- const MAX = 256;
- char buf[MAX];
-
- TAssoc aVector(512);
- while (cin >> buf)
- aVector[buf]++;
- aVector.PrintAll();
- }
-
-
-
-
-
- // FUNCTION CALL OVERLOAD
- class TAssoc
- {
- friend class TAssocIterator;
- pair* vec;
- int max;
- int free;
- public:
- TAssoc(int);
- int& operator[](const char*);
- };
-
-
-
- class TAssocIterator
- {
- TAssoc* cs; // current TAssoc array
- int i; // current index
- public:
- TAssocIterator(const TAssoc& s)
- {
- cs = &s;
- i = 0;
- }
-
-
- pair* operator()() // function call operator overload
- {
- return (i < cs->free) ? &cs->vec[i++] : NULL;
- }
-
-
- };
-
-
-
- main() // count the occurrences of each word on input
- {
- const MAX = 256;
- char buf[MAX];
- TAssoc aVector(256);
-
- while (cin >> buf)
- aVector[buf]++;
- TAssocIterator next(aVector);
- pair * p;
-
- while (p = next())
- cout << p->name << ": " << p->val << '\n';
- }
-
-
-
-
- // DEREFERENCING OPERATOR (->)
- class TPtr
- {
- // ...
- X* operator->(); // class X
- };
-
-
- void f(TPtr p) // usage
- {
- p->m = 7; // (p.operator->())->m = 7;
- }
-
-
-
- // SMART POINTERS
- class TRecPtr
- {
- Rec* inCoreAddress;
- const char* ID;
- // ...
- public:
- TRecPtr(const char* p) :
- identifier(p)
- {
- inCoreAddress = NULL;
- }
- ~TRecPtr()
- {
- WriteToDisk(inCoreAddress, ID);
- }
-
-
- Rec* operator->();
- };
-
-
-
- Rec* TRecPtr::operator->()
- {
- if (inCoreAddress == NULL)
- inCoreAddress = ReadFromDisk(ID);
- return inCoreAddress;
- }
-
-
- main(int argc,
- const char* argv) // usage
- {
- for (int i = argc; i; i--)
- {
- TRecPtr p(argv[i]);
- p->update();
- }
- }
-
-
-
-
- // INCREMENT/DECREMENT OPERATOR OVERLOADING
- class TCheckedPtrToT
- {
- T* p;
- T* array;
- int size;
- public:
- // bind to array 'a' of size 's' initial value 'p'
- TCheckedPtrToT(T* p,
- T* a,
- int s);
-
- // bind to single objec initial value 'p'
- TCheckedPtrToT(T* p);
-
- T* operator++(); // prefix
- T* operator++(int); // postfix - works from Cfront 3.0 forward
-
- T* operator--(); // prefix
- T* operator--(int); // postfix - works from Cfront 3.0 forward
-
- T& operator*(); // prefix
- };
-
-
-
- void func(T a) // example of use
- {
- T v[200];
- TCheckedPtrToT p(&v[0], v, 200); // create object
- p.operator--(1);
- p.operator*() = a; // runtime error, 'p' out of range
- p.operator++();
- p.operator*() = a; // ok
- }
-
-
-
-
- // STRING CLASS IMPLEMENTATION
- #include <iostream.h>
- #include <string.h>
-
- class TString
- {
- struct srep
- {
- char* s; // pointer to data
- int n; // reference count
- srep()
- {
- n = 1;
- }
-
-
- };
-
-
- srep* p;
-
- public:
- TString(const char*); // TString x = "abc";
- TString(); // TString x;
- TString(const TString&); // TString x = TString ...
- TString& operator=(const char*);
- TString& operator=(const TString&);
- ~TString();
- char& operator[](int i);
-
- friend ostream& operator<<(ostream& ,
- const TString&);
- friend istream& operator>>(istream& ,
- TString&);
-
- friend int operator==(const TString& x,
- const char* s)
- {
- return strcmp(x.p->s, s) == 0;
- }
-
-
- friend int operator==(const TString& x,
- const TString& y)
- {
- return strcmp(x.p->s, y.p->s) == 0;
- }
-
-
- friend int operator!=(const TString& x,
- const char* s)
- {
- return strcmp(x.p->s, s) != 0;
- }
-
-
- friend int operator!=(const TString& x,
- const Tstring& y)
- {
- return strcmp(x.p->s, y.p->s) != 0;
- }
-
-
- };
-
-
-
- TString::TString() // constructor
- {
- p = new srep;
- p->s = NULL;
- }
-
-
- TString::TString(const TString& x) // copy constructor
- {
- x.p->n++;
- p = x.p;
- }
-
-
- TString::TString(const char* s)
- {
- p = new srep;
- p->s = new
- char[strlen(s) + 1];
- strcpy(p->s, s);
- }
-
-
-
- TString::~TString()
- {
- if (--p->n == 0)
- {
- delete[]p->s;
- delete p;
- }
- }
-
-
-
-
- TString& TString::operator=(const char* s)
- {
- if (p->n > 1)
- {
- // disconnect self
- p->n--;
- p = new srep;
- }
- else // free old string
- delete[]p->s;
-
- p->s = new
- char[strlen(s) + 1];
- strcpy(p->s, s);
- return *this;
- }
-
-
- TString& TString::operator=(const TString& x)
- {
- x.p->n++; // protect against 'st = st'
- if (--p->n == 0)
- {
- delete[]p - s;
- delete p;
- }
- p = x.p;
- return *this;
- }
-
-
-
-
- ostream& operator<<(ostream& s,
- const TString& x)
- {
- return s << x.p->s << " [" << x.p->n << "]\n";
- }
-
-
- istream& operator>>(istream& s,
- TString& x)
- {
- char buf[256];
- s.get(buf, 256);
- char c;
- if (s.get(c) && c != '\n')
- {
- // buffer overflow, line longer than buffer
- }
-
- x = buf;
- cout << "echo: " << x << '\n';
- return s;
- }
-
-
- void error(const char* p)
- {
- cerr << p << '\n';
- exit(1);
- }
-
-
-
-
- char& TString::operator[](int i)
- {
- if (i < 0 || strlen(p->s) < i)
- error("index out of range");
- return p->s[i];
- }
-
-
-
-
- int main() // example of usage
- {
- TString x[100];
-
- cout << "here we go!\n";
-
- for (int n = 0; cin > x[n]; n++)
- {
- if (n == 100)
- {
- error("too many strings");
- return 99;
- }
-
- TString y;
- cout << (y = x[n]);
- if (y == "done")
- break;
- }
-
- cout << "here we go back again!\n";
- for (int i = n - 1; 0 <= i; i--)
- cout << x[i];
-
- return 0;
- }
-
-
-
-
- // CASTING OF CLASS
- class TBase { ... } b;
- class Tdpriv : private TBase { ... } dv;
- class Tdpub : public TBase { ... } db;
- foo(TBase b) { ... }
-
- foo(b); // legal
- foo(db); // legal
- foo(dv); // NOT legal!!
- foo((TBase)dv); // legal
-
-
- // ACCESS CONTROL ADJUSTMENT
- class TBase
- {
- public:
- virtual void func(void)
- {
- }
- ;
- };
-
-
- class derived1 : private TBase
- {
- public:
- TBase::func;
- };
-
-
-
-
-
- class derived2 : private derived1
- {
- public:
- void func(void)
- {
- }
- ;
- };
-
-
- main()
- {
- derived2 * foo = new derived2;
- return 0;
- }
-
-
-
-
- // MORE ESOTERIC TRICKS
-
-
- // PASSING VARIABLE ARGUMENTS TO CONSTRUCTOR
- #include <stdarg.h>
-
- class TBase { ... TBase(int); Init(va_list); ... };
-
- class TDerived : public TBase { ... TDerived(int, ...); ... };
-
- TDerived::TDerived(int i,
- ...) :
- TBase(i)
- {
- va_list ap;
- va_start(ap, i);
- Init(ap);
- va_end(ap);
- }
-
-
-
-
-
-
-
-
-
-
-
-